#include "transmission/tcp_common.h"
#include "log.h"

#include <errno.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>



size_t tcp_safe_io(int fd, io_tag_t tag, void* buf, size_t len)
{
    int bytes_once = 0; // 每次read读取到的数据
    int bytes_wait_for_read = len; //需要读取的总数据
    int read_bytes = 0; // 已经读取的总数据
    while(bytes_wait_for_read > 0) {
        switch (tag) {
            case TCP_READ: {
                bytes_once = read(fd, buf + read_bytes, bytes_wait_for_read);
                break;
            }
            case TCP_WRITE: {
                bytes_once = write(fd, buf + read_bytes, bytes_wait_for_read);
                break;
            }
            default: {
                LOG_ERROR("unknown io tag");
                return READ_MESSAGE_SIZE_INVALID;
            }
        }
        
        if (bytes_once < 0) {
            // 对于非阻塞情况，继续操作
            if (errno == EINTR) {
                continue;
            }
            LOG_ERROR("read error");
            return READ_MESSAGE_SIZE_INVALID;
        } else if(bytes_once == 0) {
            // 套接字关闭
            break;
        }
        read_bytes += bytes_once;
        bytes_wait_for_read -= bytes_once;
    }
    // 返回实际读取到的数据量
    return read_bytes;
}

size_t tcp_safe_read(int fd, void* buf, int len)
{
    return tcp_safe_io(fd, TCP_READ, buf, len);
}

size_t tcp_safe_write(int fd, void *buf, int len)
{
    return tcp_safe_io(fd, TCP_WRITE, buf, len);
}